/*
 * HearbeatSender.java
 *
 */

package cn.com.sbell.vss.util;

import java.io.IOException;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.com.sbell.vss.Util;
import cn.com.sbell.vss.VssConstants;
import cn.com.sbell.vss.csg.vsclient.util.CSGConfiguration;
/**
 * 
 * @author Yifu.HUANG
 */
public class HeartbeatSender {
	private static final Log log = LogFactory.getLog(HeartbeatSender.class);

	private Thread senderThread;

	private volatile boolean running;

	private long interval = 120000L;

	private String asUrl;

	private String serverType;

	private String localIp;
	private String deviceId;

	private boolean isFirstHeatbeat = true;

	private HttpClient httpClient;

	public class SenderThread implements Runnable {
		public void run() {
			log.info("Hearbeat Sender Thread " + this + " started.");
			while (running) {
				try {
					log.debug("AS url is " + asUrl);
//					add vondart
//					if(CSGConfiguration.pattern.matcher(CSGConfiguration.AS_ALARM_URI).matches()){
//					emsUrl=CSGConfiguration.AS_ALARM_URI;
//					log.debug("chnaged asUrl in heartBeat sender to: "+emsUrl);
//					}
					PostMethod method = new PostMethod(asUrl + "/HeartBeat");
					method.getParams().setParameter(
							HttpMethodParams.RETRY_HANDLER,
							new DefaultHttpMethodRetryHandler(2, false));
					method.getParams().setContentCharset(
							VssConstants.DEFAULT_ENCODINIG);

					// set param
					addHttpParameter(method, "serverType", serverType);
					if (!Util.strIsNull(localIp)) {
						addHttpParameter(method, "serverIp", localIp);
					}
					if (!Util.strIsNull(deviceId)) {
						addHttpParameter(method, "deviceId", deviceId);
					}
					if (isFirstHeatbeat) {
						addHttpParameter(method, "isFirstHeatbeat", "true");
						isFirstHeatbeat = false;
					} else {
						addHttpParameter(method, "isFirstHeatbeat", "false");
					}
					log.debug("Sending Hearbeat to EMS ");
					try {
						// Execute the method.
						int statusCode = httpClient.executeMethod(method);
						method.getResponseBody();
						if (statusCode != HttpStatus.SC_OK) {
							log
									.warn("Method failed: "
											+ method.getStatusLine());
						}
					} catch (HttpException ex) {
						log.warn("HTTP protocol violation: ", ex);
					} catch (IOException ex) {
						log.warn("Http transport error: ", ex);
					} catch (Exception ex) {
						log.warn("MS server error", ex);
					} finally {
						// Release the connection.
						method.releaseConnection();
					}
				} catch (ArrayIndexOutOfBoundsException ex) {
					log.warn("ArrayIndexOutOfBoundsException", ex);
				} catch (Throwable ex) {
					log.warn("", ex);
				}
				try {
					Thread.sleep(interval);
				} catch (InterruptedException ex) {
					log.warn("InterruptedException: " + ex.getMessage());// ignore
					// it
				}
			}
			log.warn("Hearbeat Sender Thread " + this + " stopped.");
		}

		private void addHttpParameter(final PostMethod method, String name,
				String value) throws IllegalArgumentException {
			if (Util.strIsNull(value)) {
				return;
			}
			method.addParameter(name, value);
		}
	};

	public void init() {
		log.info("Init HearbeatSender ...");
		running = true;
		new Thread() {
			public void run() {
				try {
					Thread.sleep(30000);
				} catch (InterruptedException ex) {
				}
				senderThread = new Thread(new SenderThread());
				senderThread.start();
				log.debug("A new Hearbeat Sender Thread created: "
						+ senderThread);
			}
		}.start();
	}

	public void destroy() {
		log.info("Request to stop HearbeatSender ...");
		running = false;
		if (senderThread != null) {
			senderThread.interrupt();
		}
	}

	public void setInterval(long interval) {
		this.interval = interval;
	}

	public void setLocalIp(String serverIp) {
		this.localIp = serverIp;
	}

	public void setServerType(String serverType) {
		this.serverType = serverType;
	}

	public void setAsUrl(String asUrl) {
		this.asUrl = asUrl;
	}

	public void setHttpClient(HttpClient httpClient) {
		this.httpClient = httpClient;
	}

	/**
	 * @return the deviceId
	 */
	public String getDeviceId() {
		return deviceId;
	}

	/**
	 * @param deviceId the deviceId to set
	 */
	public void setDeviceId(String deviceId) {
		this.deviceId = deviceId;
	}
}
